package com.relytosoft.mizar.media.analyze.services.controller.structure;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.relytosoft.dubhe.common.core.base.page.PageQuery;
import com.relytosoft.dubhe.common.core.exception.ServiceException;
import com.relytosoft.dubhe.common.core.object.ResponseResult;
import com.relytosoft.dubhe.common.core.utils.CommonUtils;
import com.relytosoft.dubhe.common.log.annotation.OpLog;
import com.relytosoft.dubhe.common.log.enums.OpTypeEnum;
import com.relytosoft.mizar.media.analyze.api.entity.structure.AyStructureDisposition;
import com.relytosoft.mizar.media.analyze.api.pojo.dto.AyStruControlVehicleDto;
import com.relytosoft.mizar.media.analyze.api.pojo.dto.AyStructureDispositionDto;
import com.relytosoft.mizar.media.analyze.api.pojo.query.AyStructureDispositionQuery;
import com.relytosoft.mizar.media.analyze.api.pojo.vo.AyBatchVo;
import com.relytosoft.mizar.media.analyze.services.service.structure.AyStructureDispositionService;
import com.relytosoft.mizar.media.common.constant.ControlConstants;
import com.relytosoft.mizar.media.common.entity.pojo.dto.controlPlan.TimeSpanDto;
import com.relytosoft.mizar.media.common.enums.ControlStatusEnum;
import com.relytosoft.mizar.media.common.enums.DeleteStatusEnum;
import com.relytosoft.mizar.media.common.enums.PlanTypeEnum;
import com.relytosoft.mizar.media.common.enums.StruDispositionTypeEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author: zyc
 * @version: v1.0
 * @description: com.relytosoft.mizar.analyze.structure.services.controller
 * @Date: 2022/5/18 15:21
 */
@Api(tags = {"结构化布控任务"})
@RestController
@RequestMapping("analyze/structure/disposition")
public class AyStructureDispositionController {

    @Resource
    private AyStructureDispositionService structureDispositionService;

    @SaCheckPermission("structure:disposition:list")
    @OpLog(msg = "查询结构化布控任务列表", opType = OpTypeEnum.SELECT)
    @ApiOperation("查询结构化布控任务列表")
    @GetMapping({"/list"})
    public ResponseResult<Map<String, Object>> select(PageQuery pageQuery, AyStructureDispositionQuery dispositionQuery) {
        validateDate(dispositionQuery);
        return ResponseResult.ok(CommonUtils.getPageData(structureDispositionService.selectStruDispositionPageList(pageQuery, dispositionQuery)));
    }

    @SaCheckPermission("structure:disposition:insert")
    @OpLog(msg = "创建结构化布控任务", opType = OpTypeEnum.INSERT)
    @ApiOperation("创建结构化布控任务")
    @PostMapping({"/insert"})
    public ResponseResult<AyBatchVo> insert(@RequestBody AyStructureDispositionDto dispositionDto) {
        //参数验证
        String strMes = validateDisposition(dispositionDto);
        if (StrUtil.isNotEmpty(strMes)) {
            throw new ServiceException(strMes);
        }
        return ResponseResult.ok(structureDispositionService.insertAyStructureDisposition(dispositionDto));
    }

    @SaCheckPermission("structure:disposition:update")
    @OpLog(msg = "修改结构化布控任务", opType = OpTypeEnum.UPDATE)
    @ApiOperation("修改结构化布控任务")
    @PutMapping({"/update"})
    public ResponseResult<AyBatchVo> update(@RequestBody AyStructureDispositionDto dispositionDto) {
        //参数验证
        String strMes = validateDisposition(dispositionDto);
        if (StrUtil.isNotEmpty(strMes)) {
            throw new ServiceException(strMes);
        }
        return ResponseResult.ok(structureDispositionService.updateAyStructureDisposition(dispositionDto));
    }

    @SaCheckPermission("structure:disposition:delete")
    @OpLog(msg = "删除结构化布控任务", opType = OpTypeEnum.DELETE)
    @ApiOperation("删除结构化布控任务")
    @PutMapping({"/delete"})
    public ResponseResult<AyBatchVo> delete(@RequestBody List<Integer> list) {
        //参数验证
        if (list == null || list.size() == 0) {
            throw new ServiceException("请选择需要删除的布控任务！");
        }
        return ResponseResult.ok(structureDispositionService.deleteAyStructureDisposition(list));
    }

    @SaCheckPermission("structure:disposition:start")
    @OpLog(msg = "启动结构化布控任务", opType = OpTypeEnum.OTHER)
    @ApiOperation("启动结构化布控任务")
    @PostMapping({"/start"})
    public ResponseResult<AyBatchVo> start(@RequestBody List<Integer> list) {
        //参数验证
        if (list == null || list.size() == 0) {
            throw new ServiceException("请选择需要启动的布控任务！");
        }
        return ResponseResult.ok(structureDispositionService.startStructureDisposition(list));
    }

    @SaCheckPermission("structure:disposition:stop")
    @OpLog(msg = "停止结构化布控任务", opType = OpTypeEnum.OTHER)
    @ApiOperation("停止结构化布控任务")
    @PostMapping({"/stop"})
    public ResponseResult<AyBatchVo> stop(@RequestBody List<Integer> list) {
        //参数验证
        if (list == null || list.size() == 0) {
            throw new ServiceException("请选择需要启动的布控任务！");
        }
        return ResponseResult.ok(structureDispositionService.stopStructureDisposition(list));
    }

   /*
   //布控布防冲突，取消布防撤防状态，任务的启停==布防撤防
   @SaCheckPermission("structure:disposition:defense")
    @OpLog(msg = "布防/撤防", opType = OpTypeEnum.OTHER)
    @ApiOperation("布防/撤防")
    @PostMapping({"/defense"})
    public ResponseResult<Void> defense(@RequestBody List<Integer> list) {
        boolean isSuccess = structureDispositionService.armedAndDisarmed(list);
        if (isSuccess) {
            return ResponseResult.ok("成功");
        } else {
            return ResponseResult.fail("操作失败");
        }
    }*/

    @SaCheckPermission("structure:disposition:temp")
    @OpLog(msg = "设置临时车辆库白名单", opType = OpTypeEnum.OTHER)
    @ApiOperation("设置临时车辆库白名单")
    @PostMapping({"/temp"})
    public ResponseResult<Void> updateTempVehicleGroup(@RequestBody AyStruControlVehicleDto controlVehicleDto) {
        AyStructureDisposition structureDisposition = structureDispositionService.getById(controlVehicleDto.getId());
        if (structureDisposition == null || structureDisposition.getIsDeleted() == DeleteStatusEnum.DELETED.getValue()) {
            return ResponseResult.fail("布控任务不存在");
        }
        //只有白名单 车辆库布控可设置临时名单
        if (!structureDisposition.getDispositionType().equals(StruDispositionTypeEnum.VEHICLEGROUP.getValue()) || !structureDisposition.getAlarmType().equals(0)) {
            return ResponseResult.fail("不符合设置临时车辆库白名单条件");
        }
        boolean isSuccess = structureDispositionService.updateTempVehicleGroup(controlVehicleDto);
        if (isSuccess) {
            //重新查询布控任务信息
            structureDisposition = structureDispositionService.getById(controlVehicleDto.getId());
            //运行中时需要更改redis缓存中的布控任务信息
            if (structureDisposition.getStatus() == ControlStatusEnum.RUNING.getValue()) {
                structureDispositionService.createRedis(structureDisposition);
            }
            return ResponseResult.ok("成功");
        } else {
            return ResponseResult.fail("操作失败");
        }
    }

    @SaCheckPermission("structure:disposition:getInfo")
    @OpLog(msg = "结构化布控任务详细信息", opType = OpTypeEnum.OTHER)
    @ApiOperation("结构化布控任务详细信息")
    @GetMapping({"/getInfo/{dispositionId}"})
    public ResponseResult<AyStructureDisposition> get(@PathVariable Integer dispositionId) {
        if (Objects.isNull(dispositionId) || dispositionId.equals(0)) {
            throw new ServiceException("参数异常");
        }
        return ResponseResult.ok(structureDispositionService.getAyStructureDispositionById(dispositionId));
    }

    private void validateDate(AyStructureDispositionQuery dispositionQuery) {
        try {
            boolean hasStart = StrUtil.isNotEmpty(dispositionQuery.getBeginTime());
            boolean hasEnd = StrUtil.isNotEmpty(dispositionQuery.getEndTime());
            if (hasStart && hasEnd) {
                Date startTime = DateUtils.parseDate(dispositionQuery.getBeginTime(), new String[]{"yyyy-MM-dd"});
                Date endTime = DateUtils.parseDate(dispositionQuery.getEndTime(), new String[]{"yyyy-MM-dd"});
                if (startTime.after(endTime)) {
                    throw new ServiceException("开始时间大于结束时间！");
                }
            }
        } catch (Exception ex) {
            throw new ServiceException(ex.getMessage());
        }
    }

    private String validateDisposition(AyStructureDispositionDto dispositionDto) {
        Integer type = dispositionDto.getDispositionType();
        Integer alarmType = dispositionDto.getAlarmType();
        if (type.equals(StruDispositionTypeEnum.TEXT.getValue())) {
            alarmType = 1;
            if (StrUtil.isEmpty(dispositionDto.getDispositionText())) {
                return "请选择布控的条件";
            }
        } else if (type.equals(StruDispositionTypeEnum.IMAGE.getValue())) {
            alarmType = 1;
            if (StrUtil.isEmpty(dispositionDto.getDispositionImage())) {
                return "请选择布控的图片";
            }
            if (Objects.isNull(dispositionDto.getThreshold())) {
                return "相似度不能为空";
            }
        } else if (type.equals(StruDispositionTypeEnum.VEHICLEGROUP.getValue())) {
            if (StrUtil.isEmpty(dispositionDto.getVehicleGroup()) && StrUtil.isEmpty(dispositionDto.getTempVehicleGroup())) {
                return "请选择布控的车辆库";
            }
            if (!dispositionDto.getDispositionCategory().equals(ControlConstants.STRUCTURE_DISPOSITION_CATEGORY_VEHICLE)) {
                return "布控类型与方式不匹配";
            }
        }
        dispositionDto.setAlarmType(alarmType);
        //模板计划验证
        if (dispositionDto.getPlanTemplateId() == null||dispositionDto.getPlanTemplateId()==0) {
            Integer planType = dispositionDto.getPlanType();
            String planInfo = dispositionDto.getPlanInfoList();
            if(planType==null){
                return "布防计划参数异常";
            }
            //非 全天计划时
            if (planType != PlanTypeEnum.ALL_DAY_PLAN.getValue()) {
                if(Objects.isNull(planInfo)||planInfo.isEmpty()){
                    return "布防计划参数异常";
                }
                //验证是否有计划信息
                try {
                    List<List<TimeSpanDto>> planInfoDtoS = JSON.parseObject(planInfo, new TypeReference<List<List<TimeSpanDto>>>() {
                    });
                    if(planInfoDtoS.isEmpty()){
                        return "布防计划参数异常";
                    }
                    //日计划
                    if(planType==PlanTypeEnum.DAY_PLAN.getValue()){
                        if(planInfoDtoS.size()!=1){
                            return "布防计划参数异常";
                        }
                        if(planInfoDtoS.get(0).isEmpty()){
                            return "布防计划参数异常";
                        }
                    }
                    //周计划
                    else if(planType==PlanTypeEnum.WEEK_PLAN.getValue()){
                        if(planInfoDtoS.size()!=7){
                            return "布防计划参数异常";
                        }
                        boolean hasTime=false;
                        for(List<TimeSpanDto> timeSpanDtos:planInfoDtoS){
                            if(!timeSpanDtos.isEmpty()){
                                hasTime=true;
                                break;
                            }
                        }
                        if(!hasTime){
                            return "布防计划参数异常";
                        }
                    }
                    else{
                        return "布防计划参数异常";
                    }
                } catch (Exception e) {
                    return "布防计划参数异常";
                }
            }
        }
        return "";
    }
}
